﻿using BCCommon.Enums;
using BCData.IM.CustomerService;
using BCDto.IM.CustomerService;
using BCEntity.IM.CustomService;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BCService.IM.CustomerService
{
    /// <summary>
    /// 在线客服服务
    /// </summary>
    public class CustomerService : ICustomerService
    {
        private readonly IApplicationContextService applicationContextService;
        private readonly ICustomerServiceData customerServiceData;
        private readonly ICustomerReceptionRecordData customerReceptionRecordData;

        public CustomerService(IApplicationContextService applicationContextService,
            ICustomerServiceData customerServiceData,
            ICustomerReceptionRecordData customerReceptionRecordData)
        {
            this.applicationContextService = applicationContextService;
            this.customerServiceData = customerServiceData;
            this.customerReceptionRecordData = customerReceptionRecordData;
        }

        public void Connect()
        {
            // TODO: 是否需要判断仅限将有客服职能的加入到 CustomerService 表?

            var customerService = this.customerServiceData.GetCustomerServiceAsync(applicationContextService.Admin.AdminId).Result;

            if (customerService == null)
            {
                this.customerServiceData.InsertAsync(new CustomerServiceEntity
                {
                    AdminId = applicationContextService.Admin.AdminId,
                    FirstLogonTime = DateTime.Now,
                    HeartbeatTime = DateTime.Now,
                    TotalReceptionCount = 0,
                    CurrentReceptionCount = 0,
                    OnlineCount = 1
                });
            }
            else
            {
                customerService.HeartbeatTime = DateTime.Now;
                customerService.OnlineCount += 1;

                this.customerServiceData.UpdateAsync(customerService);
            }
        }

        public void Disconnect()
        {
            var customerService = this.customerServiceData.GetCustomerServiceAsync(applicationContextService.Admin.AdminId).Result;

            if (customerService != null)
            {
                customerService.HeartbeatTime = DateTime.Now;
                customerService.OnlineCount -= 1;

                if (customerService.OnlineCount < 0)
                {
                    customerService.OnlineCount = 0;
                }

                this.customerServiceData.UpdateAsync(customerService);
            }
        }

        public CustomerServiceDto GetRepresentative(string businessType, string countyCode)
        {
            if (string.IsNullOrWhiteSpace(countyCode))
            {
                countyCode = "371525";
            }

            var list = this.customerServiceData.GetCustomerServicesAsync(countyCode).Result;

            var representative = list.Where(p => p.OnlineCount > 0).OrderBy(p => p.CurrentReceptionCount).FirstOrDefault();

            if (representative != null)
            {
                return representative.TransformTo<CustomerServiceDto>();
            }

            representative = list.OrderBy(p => p.CurrentReceptionCount).FirstOrDefault();

            if (representative != null)
            {
                return representative.TransformTo<CustomerServiceDto>();
            }

            return null; // 人都去哪里了???
        }
        
        public void Touch(string businessType, string referenceNumber, long adminId, RoleType userType, long userId)
        {
            var customerService = this.customerServiceData.GetCustomerServiceAsync(adminId).Result;

            if (customerService == null)
            {
                this.customerServiceData.InsertAsync(new CustomerServiceEntity
                {
                    AdminId = adminId,
                    TotalReceptionCount = 1,
                    CurrentReceptionCount = 1,
                    OnlineCount = 0
                });
            }
            else
            {
                customerService.TotalReceptionCount += 1;
                customerService.CurrentReceptionCount += 1;

                this.customerServiceData.UpdateAsync(customerService);
            }

            this.customerReceptionRecordData.InsertAsync(new CustomerReceptionRecordEntity
            {
                BusinessType = businessType,
                ReferenceNumber = referenceNumber,
                AdminId = adminId,
                UserType = userType.ToString(),
                UserId = userId,
                CreateTime = DateTime.Now
            });
        }

        public void Drop(string businessType, string referenceNumber, long adminId, RoleType userType, long userId, string reason)
        {
            var customerService = this.customerServiceData.GetCustomerServiceAsync(adminId).Result;

            if (customerService != null)
            {
                customerService.CurrentReceptionCount -= 1;

                if (customerService.CurrentReceptionCount < 0)
                {
                    customerService.CurrentReceptionCount = 0;
                }

                this.customerServiceData.UpdateAsync(customerService);
            }

            var customerReceptionRecord = this.customerReceptionRecordData.GetCustomerReceptionRecordAsync(businessType, referenceNumber, adminId, userType, userId).Result;

            if (customerReceptionRecord != null)
            {
                customerReceptionRecord.Closed = true;
                customerReceptionRecord.CloseTime = DateTime.Now;
                customerReceptionRecord.Reason = reason;
                customerReceptionRecord.Duration = (int)(DateTime.Now - customerReceptionRecord.CreateTime).TotalMinutes;

                this.customerReceptionRecordData.UpdateAsync(customerReceptionRecord);
            }
        }
    }
}
